package com.skivingcloud.file.store;

import com.skivingcloud.common.exceptions.BusinessException;
import com.skivingcloud.file.entity.SysFile;
import com.skivingcloud.file.utils.FilePathUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.*;

/**
 * 文件存储方案的实现，本地文件系统
 * @author hushouquan
 * @since 2024/1/22
 */
@Service("fsFileStorageDao")
public class FsFileStorageDaoImpl implements FileStorageDao{
    @Value("${skivingcloud.file.location:D:\\tmp\\}")
    private String fileLocation;
    /**
     * 保存文件的方法
     *
     * @param fileManagement  文件对象
     * @param fileInputStream 文件流
     * @throws Exception 异常
     */
    @Override
    public String saveFile(SysFile fileManagement, InputStream fileInputStream) throws Exception{
        String newPath = FilePathUtil.getFileFolder(fileLocation);
        File file = new File(newPath + fileManagement.getId() + "@" + fileManagement.getFileName());
        try (OutputStream outputStream = new FileOutputStream(file)) {
            byte[] buffer = new byte[fileInputStream.available()];
            fileInputStream.read(buffer);
            outputStream.write(buffer);
            return newPath + fileManagement.getId() + "@" + fileManagement.getFileName();
        } catch (IOException e) {
            throw new BusinessException("保存文件失败", e);
        } finally {
            if (fileInputStream != null) {
                fileInputStream.close();
            }
        }
    }
    
    /**
     * 读取文件的方法
     *
     * @param fileManagement 文件对象
     * @return 文件流
     * @throws Exception 异常
     */
    @Override
    public InputStream getFile(SysFile fileManagement) throws Exception{
        return new FileInputStream(fileManagement.getFilePath());
    }
    
    /**
     * 作废或删除文件，实际上是把文件移动到“作废”或“已删除”文件夹下
     *
     * @param fileManagement 文件对象
     * @param fileState      状态：1-正常、2-作废、3-删除
     * @throws Exception 异常
     */
    @Override
    public void moveFilePath(SysFile fileManagement, String fileState) throws Exception{
        FileInputStream fis = null;
        FileOutputStream fos = null;
        String fileRoot = fileLocation + (fileState.equals("2") ? "作废" : "已删除" + File.separator);
        try {
            fis = new FileInputStream(fileManagement.getFilePath());//创建输入流对象
            File fileOld = new File(fileManagement.getFilePath());
            String newPath;
            if(System.getProperty("os.name").toLowerCase().startsWith("win")) {
                newPath = fileManagement.getFilePath().replaceFirst(fileLocation.replaceAll("\\\\", "\\\\\\\\"), fileRoot.replaceAll("\\\\", "\\\\\\\\"));
            }else {
                newPath = fileManagement.getFilePath().replaceFirst(fileLocation, fileRoot);
            }
            File dir = new File(newPath.replaceAll(fileManagement.getId() + "@" + fileManagement.getFileName(), ""));
            if (!dir.exists()) {
                // 判断目录是否存在
                dir.mkdirs();
            }
            File file = new File(newPath);
            if (!file.exists()) {
                // 判断目录是否存在
                file.createNewFile();
            }
            fos = new FileOutputStream(newPath); //创建输出流对象
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fos.write(buffer);
            fileManagement.setFilePath(newPath);
            fileOld.deleteOnExit();
        } catch (Exception e) {
            throw new BusinessException("作废或删除文件失败", e);
        } finally {
            if(fis != null) {
                fis.close();
            }
            if(fos != null) {
                fos.close();
            }
        }
    }
}
